; 数码管模块常量定义
IDX_PORT EQU P2
SEG7_PORT EQU P1

; 数码管模块宏定义
SEG7_SET_NUM MACRO _SEG7_IDX, _SEG7_NUM
MOV A, #VRAM
ADD A, #_SEG7_IDX
MOV R0, A
MOV @R0, #_SEG7_NUM
ADD A, #8
MOV R0, A
MOV @R0, #0
ENDM

SEG7_SHOW_NUM MACRO _N1, _N2, _N3, _N4, _N5, _N6, _N7, _N8
	SEG7_SET_NUM 0, _N1
	SEG7_SET_NUM 1, _N2
	SEG7_SET_NUM 2, _N3
	SEG7_SET_NUM 3, _N4
	SEG7_SET_NUM 4, _N5
	SEG7_SET_NUM 5, _N6
	SEG7_SET_NUM 6, _N7
	SEG7_SET_NUM 7, _N8
ENDM

; ********数码管模块开始********
; 刷新一次数码管的显示
; 显存前8个字节存放要显示的字符的编号，后8个字节存放控制字节
;数码管数字表     0    1    2    3    4    5    6    7    8    9   NULL
SEG_NUM_TABLE: DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H, 7FH, 6FH, 0H
UPDATE_SEG7:
	PUSH ACC
	MOV IDX_PORT, #00H
	MOV SEG7_PORT, #00H
	MOV R0, #VRAM				; 从显存区取出当前要显示的字符
UPDATE_SEG7_LOOP:
	; R0表示当前指向显存区的哪一位
	MOV A, @R0
	MOV DPTR, #SEG_NUM_TABLE	; 查表得到字形码
	MOVC A, @A+DPTR
	MOV R6, A					; 将字形存入R6
	
	MOV A, R0					; R0+8从显存中取出控制字
	ADD A, #8
	MOV R0, A
	MOV A, @R0		
	
	JZ SHOW_SEG7				; 如果控制字是0，直接显示				
	SJMP NOT_SHOW_SEG7			; 如果不是0，不显示
SHOW_SEG7:
	MOV SEG7_PORT, R6			; 显示数字
	SJMP SHOW_SEG7_END
NOT_SHOW_SEG7:
	MOV SEG7_PORT, #00H
SHOW_SEG7_END:
	INC R0						; 指向下一个要显示的数字
	MOV A, R0					; R0-8
    CLR C
	SUBB A, #8
	MOV R0, A
	
	LCALL DELAY1MS
	INC IDX_PORT				; 指向下一位
	
	CJNE R0, #VRAM_ADD8, UPDATE_SEG7_LOOP
	MOV SEG7_PORT, #00H
	POP ACC
RET
; ********数码管模块结束********